package com.wili.c;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.c.Ca;
//jdk7
/**
 * Miscellanous functions.
 * 
 * @author weilai
 */
@SuppressWarnings("all")
public class Misc9 {
	static final String NL = Str9.NL;

	static final String NL1 = "\n", NULL = "null";

	static final String sups = "⁰¹²³⁴⁵⁶⁷⁸⁹", Jj = "±";// 特殊符号

	static final String GREEK_LETTER = "θαβγλμωεπ";
	public static <T> String concatArr(T[] arr, String deli, int from) {
		if (arr.length == 0)
			return "";
		if (arr.length == 1)
			return arr[0].toString();
		if (arr.length == 2)
			return arr[0].toString() + deli + arr[1].toString();
		StringBuilder sb = new StringBuilder(16 + arr.length * 4);
		for (int k = from; k < arr.length; k++) {
			if (k > from)
				sb.append(deli);
			T ele = arr[k];
			sb.append(ele);
		}
		return sb.toString();
	}

	/**
	 * Return the lineNo at given location, first lineNo is 0,...
	 * @param index
	 * @param lineNoList
	 * @see this{@link #indexListOfLines(String)}
	 * @return
	 */
	public static int lineNoAt(int index, List<Integer> lineNoList) {
		if (Boolean.FALSE) {
			indexListOfLines("");
		}
		int ret = Collections.binarySearch(lineNoList, index);//6930， ind=6932
		if (ret >= 0)
			return ret + 1;
		return -ret;//若插入点是n, 从零计数的行号就是n
	}

	/**
	 * if x>1, Line x is txt.substring(inds[i-2],inds[i-1])<br>
	 * line 1 is txt.substring(0,inds[0])
	 * @return  inds.
	 * @see this{@link #lineNoAt(int, List)}
	 */
	public static List<Integer> indexListOfLines(String txt) {
		List<Integer> lineNoList = new ArrayList<Integer>(64);
		int ind = 0;
		String NL2 = System.lineSeparator();
		if ("".isEmpty()) {
			Pattern nlPat = Pattern.compile(System.lineSeparator() + "|\n|\r");//java编辑器就是这么分行的
			Matcher mat = nlPat.matcher(txt);
			int from = 0;
			int times = 0;
			while (mat.find()) {
				//System.out.println(++times + ":" + text.substring(from, mat.start()));
				lineNoList.add(mat.start());
				if (times == 99)
					Ca.pause();
				from = mat.end();
			}
			return lineNoList;
		}
		int from = 0, times = 0;
		while ((ind = txt.indexOf(NL1, ind)) != -1) {
			String st = txt.substring(from, ind).toString();
			System.out.println(++times + ":" + st);
			int valu = (int) txt.charAt(ind + 3);
			if (times == 99)
				Ca.pause();
			lineNoList.add(ind);
			ind += NL1.length();
			from = ind;
		}
		System.out.println(++times + ":" + txt.substring(from).toString());
		return lineNoList;
	}

	public static List<Double> listOfNums(double... dd) {
		List<Double> list = new ArrayList<Double>(dd.length);
		for (double d : dd) {
			list.add(d);
		}
		return list;
	}
	static final String yyMMdd_HHmmssStr = "yyyy-MM-dd HH:mm:ss";

	static final String yyMMdd_HHmmssStrSSS = "yyyy-MM-dd HH:mm:ss.SSS";
	public static String strOfList(Collection list, int showLineNo, String separator) {
		boolean hasLineNo = showLineNo == 1 && separator.startsWith("\n");
		StringBuilder sb = new StringBuilder(list.size() * 16);
		int ind = 0;
		for (Object ele : list) {
			//for (int i = 0; i < list.size(); i++) {
			if (++ind > 1)
				sb.append(separator);
			if (hasLineNo) {
				sb.append(String.format("%1$-3s", ind) + ": ");
			}
			if (ele == null) {
				sb.append(ele);
			} else if (ele instanceof Object[]) {
				Object[] aa = (Object[]) ele;
				List lis = Arrays.asList(aa);
				sb.append(lis);
			} else if (ele instanceof double[]) {
				double[] aa = (double[]) ele;
				List lis = Misc9.listOfNums(aa);
				sb.append(lis);
			} else {
				sb.append(ele.toString());
			}
		}
		return sb.toString();
	}
	public static interface Color {
		/*
		 * black red green brown blue magenta cyan white underscoreOn underscoreOff ...
		 * see: Eclipse/MyEclipse在线安装 ANSI Escape in Console 插件...
		 */
		String Deft = "\033[0m", Bold = "\033[1m", Blink = "\033[5m";

		String Black = "\033[30m", Red = "\033[31m", Green = "\033[32m", Brown = "\033[33m";

		String Blue = "\033[34m", Magenta = "\033[35m", Cyan = "\033[36m", White = "\033[37m";

		//
		String Black2 = "\033[40m", Red2 = "\033[41m", Green2 = "\033[42m", Brown2 = "\033[43m";

		String Blue2 = "\033[44m", Magenta2 = "\033[45m", Cyan2 = "\033[46m", White2 = "\033[47m";
	}
	public static void printMap(Map map) {
		if (map instanceof TreeMap) {
		} else {
			try {
				map = new TreeMap<>(map);
			} catch (Exception e) {
			}
		}
		StringBuilder sb = new StringBuilder();
		int ind = 0;
		sb.append("----Misc9.printMap:" + map.size());
		for (Object key : map.keySet()) {
			++ind;
			sb.append('\n');
			String keySt = key.toString();
			Object value = map.get(key);
			String valueSt = value == null ? "Null" : value.toString();
			keySt = String.format("%1$6s", keySt);
			sb.append(ind + "," + keySt + ": " + valueSt);
		}
		sb.append("\n----Misc9.printMap:end.");
		C2.log(1, sb);
	}
	/**
	 * 把集合分类，返回以类型为键的 list Map.
	 */
	/**
	 * 输入若干集合，返回交集。
	 * @param list
	 * @param skipInd
	 * @return
	 */
	public static final String CompileErr = "CompileErr";
	public static String strOfObjs(String deli, Object[] objs) {
		if (objs.length == 0)
			return "";
		if (objs.length == 1)
			return String.valueOf(objs[0]);
		if (objs.length == 2)
			return String.valueOf(objs[0]) + String.valueOf(objs[1]);
		int size = 0;
		for (Object ele : objs)
			size += String.valueOf(ele).length();
		StringBuilder sb = new StringBuilder(size);
		for (int i = 0; i < objs.length; i++) {
			if (!deli.isEmpty() && i > 0)
				sb.append(deli);
			sb.append(String.valueOf(objs[i]));
		}
		return sb.toString();
	}

	/**
	 *  Traverse class in jar file, until $fun return false.
	 */
	public static void traverseClassInJarFile(File jarFile, Function<Class<?>, Boolean> fun) {
		try {
			//通过将给定路径名字符串转换为抽象路径名来创建一个新File实例
			ClassLoader classLoad;
			if ("".isEmpty()) {
				URL url1 = jarFile.toURI().toURL();
				classLoad = new URLClassLoader(new URL[] { url1 }, Thread.currentThread().getContextClassLoader());
			} else {
				classLoad = ClassLoader.getSystemClassLoader();
			}
			//通过jarFile和JarEntry得到所有的类  
			JarFile jar = new JarFile(jarFile);
			//返回zip文件条目的枚举  
			Enumeration<JarEntry> enumFiles = jar.entries();
			JarEntry entry;
			//测试此枚举是否包含更多的元素  
			while (enumFiles.hasMoreElements()) {
				entry = (JarEntry) enumFiles.nextElement();
				if (entry.getName().indexOf("META-INF") < 0) {
					String classFullName = entry.getName();
					if (!classFullName.endsWith(".class")) {
						classFullName = classFullName.substring(0, classFullName.length() - 1);
					} else {
						//去掉后缀.class  
						String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");
						Class<?> myclass = null;
						try {
							myclass = classLoad.loadClass(className);
							if (!fun.apply(myclass))
								return;
						} catch (ClassNotFoundException e) {
							e.printStackTrace();
							continue;
						}
						if (Boolean.FALSE) {
							System.out.println("*****************************");
							System.out.println("全类名:" + className);
							//得到类中包含的属性  
							Method[] methods = myclass.getMethods();
							for (Method method : methods) {
								String methodName = method.getName();
								System.out.println("方法名称:" + methodName);
								Class<?>[] parameterTypes = method.getParameterTypes();
								for (Class<?> clas : parameterTypes) {
									// String parameterName = clas.getName();
									String parameterName = clas.getSimpleName();
									System.out.println("参数类型:" + parameterName);
								}
								System.out.println("==========================");
							}
						}
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static String readCmdLine(String msg) {
		InputStreamReader ir = new InputStreamReader(System.in);
		BufferedReader br = new BufferedReader(ir);
		try {
			System.out.println(msg);
			String ret = br.readLine();
			return ret == null ? "" : ret;
		} catch (IOException e) {
			return "";
		}
	}
}